package com.xiaouyudeguang.common.aop;

import com.xiaouyudeguang.common.utils.StringUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.HandlerMapping;

import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;

import static com.xiaouyudeguang.common.config.MybatisPlusConfig.TABLE_NAME;

@Slf4j
@Aspect
@Component
@AllArgsConstructor
public class DicodeAspect {

    private final HttpServletRequest request;

    private final DataSource dataSource;

    @Pointcut("execution(* com.*.*.*.service.impl.*.*(..))")
    public void autoCreateTable() {
    }

    @Around("autoCreateTable()")
    @SuppressWarnings("unchecked")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        if (RequestContextHolder.getRequestAttributes() == null) {
            return pjp.proceed();
        }
        String tableName = TABLE_NAME.get();
        if (StringUtils.isBlank(tableName)) {
            Map<String, String> pathVariables = (Map<String, String>) request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
            if (pathVariables == null || pathVariables.isEmpty()) {
                return pjp.proceed();
            }
            tableName = pathVariables.get("table_name");
        }
        if (StringUtils.isBlank(tableName)) {
            return pjp.proceed();
        }
        tableName = StringUtils.lowerCamel(tableName);
        Connection conn = null;
        try {
            conn = dataSource.getConnection();
            String[] types = new String[]{"TABLE", "VIEW"};
            ResultSet rs = conn.getMetaData().getTables(conn.getCatalog(), conn.getSchema(), "%", types);
            while (rs.next()) {
                String tableStr = rs.getString("TABLE_NAME");
                if (tableStr.equals(tableName)) {
                    return pjp.proceed();
                }
            }
            PreparedStatement ps = conn.prepareStatement(tableSQL(tableName));
            ps.execute();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return pjp.proceed();
    }

    public static String tableSQL(String tableName) {
        return "CREATE TABLE `" + tableName + "`  (\n" +
                "  `id` bigint NOT NULL primary key comment '主键id' ,\n" +
                "  `app_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL comment '应用id',\n" +
                "  `tenant_id` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL comment '租户id',\n" +
                "  `created` datetime(0) NULL DEFAULT NULL comment '创建时间',\n" +
                "  `creator` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL comment '创建人',\n" +
                "  `modified` datetime(0) NULL DEFAULT NULL comment '修改时间',\n" +
                "  `modifier` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL comment '修改人',\n" +
                "  `status` bigint NULL DEFAULT 0 comment '状态',\n" +
                "  `is_default` bigint default 1 comment '是否默认',\n" +
                "  `json` json NOT NULL comment '扩展字段',\n" +
                "  `sort` int default 100000 comment '排序'\n" +
                ") ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '" + tableName + "' ROW_FORMAT = Dynamic;";
    }
}
